package com.ecoolex.ying.space.admin.graphql;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.*;
import com.ecoolex.ying.space.admin.core.AdminConstant;
import com.ecoolex.ying.space.entity.GoodsBrand;
import com.ecoolex.ying.space.entity.GoodsCategory;
import com.ecoolex.ying.space.entity.GoodsCategory.Column;
import com.ecoolex.ying.space.pojo.AddGoodsCategoryDTO;
import com.ecoolex.ying.space.pojo.EditGoodsCategoryDTO;
import com.ecoolex.ying.space.pojo.QueryGoodsCategoryDTO;
import com.ecoolex.ying.space.ws.GoodsCategoryService;
import com.google.common.collect.Lists;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import java.util.List;

@GraphQL2Module(type = GraphQL2Module.Type.Admin, description = "商品分类管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY, key = GoodsCategoryGraphql.AUTH, name = "商品分类管理")
public class GoodsCategoryGraphql {

    public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-GOODS-CATEGORY";

    @Reference
    private GoodsCategoryService goodsCategoryService;

    @Autowired
    private StorageService storageService;

    @TypeField(type = GoodsCategory.class, field = "parent", description = "父分类")
    public GoodsCategory parent(@Source GoodsCategory source) {
        if (Check.notNullAndGtZero(source.getParentCategoryId())) {
            return goodsCategoryService.getCategoryById(source.getParentCategoryId());
        }
        return null;
    }

    @TypeField(type = GoodsCategory.class, field = "child", description = "子分类列表")
    public List<GoodsCategory> child(@Source GoodsCategory source, Boolean isShow) {
        return goodsCategoryService.queryCategoryByParentId(source.getCategoryId(), isShow);
    }

    @TypeField(type = GoodsCategory.class, field = "image", description = "图片")
    public StorageInfo image(@Source GoodsCategory source) {
        return storageService.get(source.getImage());
    }

    @TypeField(type = GoodsCategory.class, field = "canEdit", description = "能否编辑")
    public boolean canEdit(@Source GoodsCategory source, AdminMemberAuthority user) {
        return user.auth(AUTH_EDIT);
    }

    @TypeField(type = GoodsCategory.class, field = "canDel", description = "能否删除")
    public boolean canDel(@Source GoodsCategory source, AdminMemberAuthority user) {
        return user.auth(AUTH_DEL);
    }

    @TypeField(type = GoodsCategory.class, field = "canSetShow", description = "是否能设置展示")
    public Boolean canSetShow(@Source GoodsCategory source) {
        return !source.getIsShow();
    }

    @TypeField(type = GoodsCategory.class, field = "canSetHide", description = "是否能设置隐藏")
    public Boolean canSetHide(@Source GoodsCategory source, AdminMemberAuthority user) {
        return source.getIsShow();
    }

    private static final String AUTH_GET = AUTH + "-GET";

    @QueryField(field = "goodsCategory", description = "获取商品分类详情")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "获取商品分类详情")
    public GoodsCategory get(@NonNull Integer categoryId, AdminMemberAuthority user) {
        user.assertLogin();
        return goodsCategoryService.getCategoryById(categoryId);
    }

    private static final String AUTH_QUERY = AUTH + "-QUERY";

    @QueryField(field = "goodsCategoryList", description = "查询商品分类列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "查询商品分类列表")
    public Pagination<GoodsCategory> queryCategory(@NonNull QueryGoodsCategoryDTO query, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertLogin();
        return goodsCategoryService.queryCategory(query, sorts, page);
    }

    @MutationField(field = "uploadGoodsCategoryImage", description = { "上传商品分类图片" })
    public StorageInfo uploadGoodsCategoryImage(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("GoodsCategory","Image");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(2));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());
        
        return storageService.upload(request,uploadSource,uploadLimit);
    }

    private static final String AUTH_ADD = AUTH + "-ADD";

    @MutationField(field = "addGoodsCategory", description = "添加商品分类")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加商品分类")
    public GoodsCategory add(@NonNull AddGoodsCategoryDTO add, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ADD);
        return goodsCategoryService.addCategory(add, user.userName());
    }

    private static final String AUTH_EDIT = AUTH + "-EDIT";

    @MutationField(field = "editGoodsCategory", description = "编辑商品分类")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑商品分类")
    public GoodsCategory edit(@NonNull EditGoodsCategoryDTO edit, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        GoodsCategory old = goodsCategoryService.getCategoryById(edit.getCategoryId());
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "分类不存在");
        BeanUtil.copy(edit,
                old,
                Lists.newArrayList(Column.level,
                        Column.isShow,
                        Column.deleted,
                        Column.createUser,
                        Column.createTime).stream().map(Column::getJavaProperty).toArray(String[]::new));
        return goodsCategoryService.updateCategory(old, user.userName());
    }

    private static final String AUTH_DEL = AUTH + "-DEL";

    @MutationField(field = "delGoodsCategory", description = "删除商品分类")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除商品分类")
    public Boolean del(@NonNull Integer categoryId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_DEL);
        GoodsCategory record = goodsCategoryService.getCategoryById(categoryId);
        Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "分类不存在");
        goodsCategoryService.deleteCategory(record, user.userName());
        return true;
    }


    private static final String AUTH_SHOW = AUTH + "-SHOW";

    @MutationField(field = "setShowGoodsCategory", description = "设置展示商品分类")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_SHOW, name = "设置展示商品分类")
    public GoodsCategory show(@NonNull Integer categoryId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_SHOW);
        GoodsCategory record = goodsCategoryService.getCategoryById(categoryId);
        Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "分类不存在");
        return goodsCategoryService.showCategory(record, user.userName());
    }

    private static final String AUTH_HIDE = AUTH + "-HIDE";

    @MutationField(field = "setHideGoodsCategory", description = "设置隐藏商品分类")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_HIDE, name = "设置隐藏商品分类")
    public GoodsCategory hide(@NonNull Integer categoryId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_HIDE);
        GoodsCategory record = goodsCategoryService.getCategoryById(categoryId);
        Assert.isTrue(Check.notNull(record), ResultCode.VERIFY.build(1), "分类不存在");
        return goodsCategoryService.hideCategory(record, user.userName());
    }

}
